<template>
    <a-modal v-model:open="visible" title="修改头像" :destroy-on-close="destroyOnClose" width="860px" :mask-closable="maskClosable" @close="close" @ok="submit">
        <div class="content">
            <div class="cut-image">
                <vue-cropper ref="cropperRef" :img="cropper.image" :auto-crop="cropper.autoCrop" :auto-crop-width="cropper.autoCropWidth" :auto-crop-height="cropper.autoCropHeight" :fixed-box="cropper.fixedBox" :output-type="cropper.outputType" @real-time="onRealTime" />
            </div>
            <div v-dompurify-html="cropper.previews.html" class="preview"></div>
        </div>

        <div class="footer">
            <a-upload v-model:file-list="upload.fileList" name="file" :action="upload.action" :headers="upload.headers" @change="handleChange">
                <a-button class="upload">
                    <template #icon><UploadOutlined /></template>上传
                </a-button>
            </a-upload>
            <a-button @click="scale(1)">
                <template #icon><PlusOutlined /></template>
            </a-button>
            <a-button @click="scale(-1)">
                <template #icon><MinusOutlined /></template>
            </a-button>
            <a-button @click="rotate(false)">
                <template #icon><UndoOutlined /></template>
            </a-button>
            <a-button @click="rotate(true)">
                <template #icon><RedoOutlined /></template>
            </a-button>
        </div>
    </a-modal>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { UploadOutlined, PlusOutlined, MinusOutlined, UndoOutlined, RedoOutlined } from '@ant-design/icons-vue'
import { useModal } from '@iframe/tools/mixins/ModelDrawerMixins'
import { VueCropper } from 'vue-cropper'
import { useTokenStore } from '@iframe/tools/store/modules/token'
import { ACCESS_TOKEN } from '@iframe/tools/config/SystemConfig'
import http, { SUCCESS_CODE } from '@iframe/tools/axios/axios'
import 'vue-cropper/dist/index.css'

const { visible, destroyOnClose, maskClosable, close } = useModal()
const cropperRef = ref()
const tokenStore = useTokenStore()
const emits = defineEmits(['close'])

const cropper = reactive({
    image: null,
    autoCropWidth: 200, //默认生成截图框宽度
    autoCropHeight: 200, //默认生成截图框高度
    autoCrop: true, //是否默认生成截图框
    fixedBox: true,
    outputType: 'png',
    previews: {}
})

const upload = reactive({
    fileList: [],
    headers: {},
    action: `/api/${import.meta.env.IFRAME_CONTEXT_PATH}/upload`
})
upload.headers[ACCESS_TOKEN] = `Bearer ${tokenStore.getToken}`

const handleChange = ({ file }) => {
    if (file.status === 'done') {
        if (file.response.code === 200) {
            changeCropperImage(file.response.data)
        }
    }
}

const scale = size => {
    cropperRef.value.changeScale(size)
}

const rotate = direct => {
    if (direct) {
        cropperRef.value.rotateRight()
    } else {
        cropperRef.value.rotateLeft()
    }
}

const onRealTime = data => {
    cropper.previews = data
}

const submit = () => {
    cropperRef.value.getCropBlob(data => {
        let formData = new FormData()
        formData.append('file', data, 'avatar.png')
        http.post(`${import.meta.env.IFRAME_CONTEXT_PATH}/upload`, formData, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        }).then(result => {
            if (result.code === SUCCESS_CODE) {
                emits('close', result.data)
                close()
            }
        })
    })
}

const changeCropperImage = (imagePath, callback) => {
    const reader = new FileReader()
    reader.onload = e => {
        cropper.image = e.target.result
        callback && callback()
    }
    http.get(`/${import.meta.env.IFRAME_CONTEXT_PATH}/image?filePath=${imagePath}`, {
        responseType: 'blob'
    }).then(result => {
        reader.readAsDataURL(result.data)
    })
}

const open = image => {
    changeCropperImage(image, () => {
        visible.value = true
    })
}
defineExpose({ open })
</script>
<style lang="less" scoped>
.content {
    display: flex;
    justify-content: space-between;
    .cut-image {
        width: 400px;
        height: 400px;
        text-align: center;
    }
    .preview {
        width: 400px;
        height: 400px;
        padding: 100px;
        :deep(.show-preview) {
            border-radius: 50%;
            overflow: hidden;
        }
    }
}

.footer {
    margin-top: 5px;
    padding: 10px 0;
    .upload {
        margin-right: 30px !important;
    }
    :deep(.ant-btn) {
        margin: 0 5px 0;
    }
    :deep(.ant-upload-list) {
        display: none;
    }
}
</style>
